package com.googlecode.gaetwbot.cron;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slim3.datastore.Datastore;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.labs.taskqueue.QueueFactory;
import com.google.appengine.api.labs.taskqueue.TaskOptions;
import com.google.appengine.api.labs.taskqueue.TaskOptions.Method;
import com.googlecode.gaetwbot.service.MentionService;
import com.googlecode.gaetwbot.service.SettingService;

/**
 * 新着のmentionsをチェックし、ひとつひとつのmentionに対する処理を行うTaskQueueに処理を引渡す。
 * <p>新着のmentionが存在し、TaskQueueに処理を渡した場合はログインユーザからつぶやいてみたり。</p>
 * @author shin1ogawa
 */
@SuppressWarnings("serial")
public class CheckMentions extends HttpServlet {

	static final Logger logger = Logger.getLogger(CheckMentions.class.getName());


	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
		// twitterのアカウント情報を取得する
		String twitterUser = SettingService.get("twitterUser");
		String twitterPassword = SettingService.get("twitterPassword");
		if (StringUtils.isEmpty(twitterUser) || StringUtils.isEmpty(twitterPassword)) {
			logger.warning("twitterアカウントの設定が存在しません。");
			return;
		}
		Twitter twitter = new Twitter(twitterUser, twitterPassword);
		// 前回取得したMentionsの最大IDを取得する
		String lastMentionIdString = SettingService.get("lastMentionId");
		long lastMentionId = lastMentionIdString != null ? Long.valueOf(lastMentionIdString) : 0;
		List<Status> mentions = null;
		try {
			mentions = twitter.getMentions();
		} catch (TwitterException e) {
			logger.log(Level.WARNING, "mentionsの取得に失敗しました。", e);
		}
		int count = 0; // 処理件数
		for (Status status : mentions) {
			long id = status.getId();
			if (id <= lastMentionId) {
				// これ以降は以前の処理対象となったmentionなので処理を中断する
				logger.fine("処理済みのmentionなのでスキップします。id=" + id);
				break;
			}
			// mentionごとの処理を分散実行するためにDefaultQueueにTaskを投入する。
			// その際、mentionを一旦データストアに保存し、保存したmentionの主キーのエンコード値をTaskに渡す。
			// Task側では渡された主キーのエンコード値から主キーを復元し、
			// それを使ってデータストアからmentionを読み出して必要な処理を行えば良い。
			Key key = MentionService.put(status);
			QueueFactory.getDefaultQueue().add(
					TaskOptions.Builder.url("/tq/processMention").method(Method.GET).param(
							"encodedKey", Datastore.keyToString(key)));
			count++;
		}
		if (count > 0) {
			long id = mentions.get(0).getId();
			logger.info("lastMentionIdを更新します:lastMentionId=" + String.valueOf(id));
			SettingService.set("lastMentionId", String.valueOf(id));
			// つぶやく
			try {
				twitter.updateStatus(count + "件のTaskを投入したよ。");
			} catch (TwitterException e) {
				logger.log(Level.WARNING, "つぶやきに失敗しました。", e);
			}
		}
	}
}
